package neptune.manager.builder;

import java.util.BitSet;

import neptune.manager.model.topology.IPAddress;
import neptune.manager.utils.IllegalValueException;
import neptune.manager.utils.UnsignedByte;

public class LinkTEST {

	/**
	 * @param args
	 * @throws IllegalValueException
	 */
	public static void main(String[] args) throws Exception {

		IPAddress addr = new IPAddress(4, "10.0.0.1", "255.255.255.0", false);
		IPAddress addr2 = new IPAddress(4, "10.0.0.2", "255.255.255.0",
				false);

		// Come ottenere l'indirizzo della subnet:

		UnsignedByte[] subnet = IPAddress.toUnsignedBytes(addr.getSubnetMask());
		UnsignedByte[] subnet2 = IPAddress.toUnsignedBytes(addr2
				.getSubnetMask());

		String subnetSTR = IPAddress.toAddressString(getSubnetAddress(addr
				.getUnsignedBytes(), subnet));
		String subnetSTR2 = IPAddress.toAddressString(getSubnetAddress(addr2
				.getUnsignedBytes(), subnet2));

		System.out.println(subnetSTR);
		System.out.println(subnetSTR2);

		System.out.println(isIncluded(addr, addr2));
	}

	private static UnsignedByte[] getSubnetAddress(UnsignedByte[] address,
			UnsignedByte[] subnet) throws IllegalValueException {

		UnsignedByte[] subnetAddr = new UnsignedByte[4];

		for (int i = 0; i < subnetAddr.length; i++) {
			BitSet addrByte = getBitValue(address[i]);
			BitSet subMByte = getBitValue(subnet[i]);

			addrByte.and(subMByte);

			subnetAddr[i] = getByteValue(addrByte);
		}

		return subnetAddr;
	}

	private static BitSet getBitValue(UnsignedByte byteVal) {
		BitSet bit = new BitSet(8);
		int val = byteVal.getValue();
		for (int i = 7; i >= 0; i--) {
			int toSub = (int) (Math.pow(2, i));
			if (val - toSub >= 0) {
				bit.set(i);
				val -= toSub;
			}
		}
		return bit;
	}

	private static UnsignedByte getByteValue(BitSet bitVal)
			throws IllegalValueException {
		int val = 0;
		for (int i = 0; i < bitVal.size(); i++) {
			if (bitVal.get(i))
				val += Math.pow(2, i);
		}

		return new UnsignedByte(val);
	}

	private static boolean isIncluded(IPAddress existing, IPAddress newNet)
			throws Exception {

		UnsignedByte[] newBytes = getSubnetAddress(newNet.getUnsignedBytes(),
				IPAddress.toUnsignedBytes(newNet.getSubnetMask()));

		UnsignedByte[] sub = getSubnetAddress(newBytes, IPAddress
				.toUnsignedBytes(existing.getSubnetMask()));

		String subStr = IPAddress.toAddressString(sub);

		return existing.getAddress().equals(subStr);
	}
}
